# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - Jadescripts Code Parser

    @copyright: 2009 Anakin Hao <ahao@jadeworld.com>
    @license: GNU GPL, see COPYING for details.
"""
import re
re.DOTALL
from MoinMoin.parser._ParserBase import ParserBase

from MoinMoin.parser._ParserBase import FormatText

Dependencies = ['user'] # the "Toggle line numbers link" depends on user's language

class Parser(ParserBase):

    parsername = 'ColorizedJade'
    extensions = ['.mth']
    Dependencies = Dependencies

    def __init__(self, raw, request, **kw):
        ParserBase.__init__(self, raw, request, **kw)
        self._ignore_case = False
        #print raw
    def setupRules(self):
        ParserBase.setupRules(self)
        
        #for JADE reserved words
        self.jade_ResWord_format = FormatText('Jade_ResWord')
        self.addRuleFormat('Jade_ResWord')
        
        #for JADE reserved words
        self.jade_sysVar_format = FormatText('Jade_SysVar')
        self.addRuleFormat('Jade_SysVar')
        
        #for JADE system classes
        self.jade_sysCls_format = FormatText('Jade_SysCls')
        self.addRuleFormat('Jade_SysCls')
        
        self.addRuleFormat("Jade_Comment")
        self.addRuleFormat("Jade_String")
        self.addRuleFormat("Jade_Number")
        self.addRuleFormat("Jade_UserCls")
        
        self.addRulePair("Jade_Comment", r"\/\*", r"\*\/")
        self.addRule("Jade_Comment", r"//.*$")
        self.addRulePair("Jade_String", r"'", r"'")
        self.addRulePair("Jade_String", r'"', r'"')
        self.addRule("Jade_Number", r"[0-9](\.[0-9]*)?(eE[+-][0-9])?|\$[0-9a-fA-F]+")
        self.addRule("ID", r"[a-zA-Z_][0-9a-zA-Z_]*")
        self.addRulePair("Jade_UserCls", r"[vars].+:", r";.+[begin]")
        
        jade_rserved_words = ['abortTransaction','abortTransientTransaction','and','Any','as',
                          'app','appContext','attributeDefinitions','begin','beginLoad',
                          'beginLock','beginTransaction','beginTransientTransaction','Binary',
                          'Boolean','break','Byte','call','categoryDefinition','Character',
                          'classMapDefinitions','_cloneOf','commitTransaction',
                          'commitTransientTransactionconstantDefinitions','constants',
                          'continue','create','currentSchema','currentSession','databaseDefinitions',
                          'databaseFileDefinitions','DatedbServerDefinitions','Decimal',
                          'defaultFileDefinition','delete','div','do','documentationText','else',
                          'elseif_encryptedSource','_endEncryptedSource','end','endExecuteWhen',
                          'endforeach','endif','endqueryeach','endLoad','endLock','endwhile','epilog',
                          'eventMethodMappings','executeWhen','exception','exportedClassDefinitions',
                          'exportedConstantDefinitions','exportedInterfaceDefinitions',
                          'exportedMethodDefinitions','exportedPackageDefinitions',
                          'exportedPropertyDefinitions','_exposedConstantDefinitions',
                          '_exposedListDefinitions','_exposedMethodDefinitions',
                          '_exposedPropertyDefinitions','externalFunctionDefinitions',
                          'externalFunctionSources','externalKeyDefinitions',
                          'externalMethodDefinitions','externalMethodSources','false','foreach',
                          'global','if','implementInterfaces','importMethod',
                          'importedPackageDefinitions','in','Integer','Integer64','continued',
                          'interfaceDefinitions','interfaceDefs','inverseDefinitions','is',
                          'JadeFiletypeVersiontag','jadeMethodDefinitions','jadeMethodSources',
                          'jadePatchRelease','jadeVersionNumber','libraryDefinitions',
                          'localeDefinitions','localeFormatDefinitions','memberKeyDefinitions',
                          'membershipDefinitions','MemoryAddress','method','methodImplementations',
                          'mod','node','not','null','of','on','or','Point','parentOf','partitionMethod',
                          'peerOf','primitive','process','queryeach','raise','read','Real',
                          'referenceDefinitions','_remapTableDefinitions','return','reversed',
                          'rootSchema','schemaDefaultLocale','schemaDefinition','schemaViewDefinitions',
                          'self','setModifiedTimeStamp','step','String','StringUtf8','subInterfaceOf',
                          'subclassOf','subschemaOf','system','terminate','then','Time','TimeStamp',
                          'TimeStampInterval','TimeStampOffset','to','translatableStringDefinitions',
                          'true','typeDefinitions','typeHeaders','typeSources','vars',
                          'webServicesClassProperties','webServicesMethodDefinitions',
                          'webServicesMethodProperties','webServicesMethodSources','where',
                          'while','write','xor']
        self.addJadeResWord(jade_rserved_words)

        jade_sysVar_words = ['self', 'app', 'global', 'system', 'node',
                             'process','currentSchema', 'rootSchema',
                             'method', 'exception', 'currentSession', 'appContext']
        self.addJadeSysVar(jade_sysVar_words)
        
        jade_sysCls_words = ['ActiveXAutomation', 'ActiveXInterface', 'ActiveXInvokeException',
                             'Application', 'ApplicationContext', 'Array', 'BinaryArray', 'BooleanArray', 
                             'Btree', 'ByteArray', 'CharacterArray', 'CMDialog', 'CMDColor', 'CMDFileOpen', 
                             'CMDFileSave', 'CMDFont', 'CMDPrint', 'Collection', 'Connection', 
                             'ConnectionException', 'ConstantNDict', 'CurrencyFormat', 'Database', 
                             'DateArray', 'DateFormat', 'DbFile', 'DbFileArray', 'DeadlockException', 
                             'DecimalArray', 'Dictionary', 'DynaDictionary', 'Exception', 'ExceptionHandlerDesc', 
                             'ExternalArray', 'ExternalCollection', 'ExternalDatabase', 'ExternalDictionary', 
                             'ExternalIterator', 'ExternalObject', 'ExternalSet', 'ExtKeyDictionary', 
                             'FatalError', 'File', 'FileException', 'FileFolder', 'FileNode', 'FileNodeArray', 
                             'Global', 'GUIClass', 'HugeStringArray', 'IDispatch', 'IDispatchArray', 
                             'Integer64Array', 'IntegerArray', 'IntegrityViolation', 'InternetPipe', 'Iterator', 
                             'IUnknown', 'JadeAuditAccess', 'JadeBytes', 'JadeDatabaseAdmin', 
                             'JadeDbFilePartition', 'JadeDotNetInvokeException', 'JadeDotNetType', 
                             'JadeDynamicObject', 'JadeDynamicObjectArray', 'JadeGenericMessage', 
                             'JadeGenericMessagingIF', 'JadeGenericQueue', 'JadeGenericQueueManager', 
                             'JadeHTMLClass', 'JadeInternetTCPIPConnection', 'JadeLicenceInfo', 'JadeLog', 
                             'JadeMessagingException', 'JadeMessagingFactory', 'JadeMetadataAnalyzer', 
                             'JadeMethodContext', 'JadeMultiWorkerTcpConnection', 'JadeMultiWorkerTcpTransport', 
                             'JadeMultiWorkerTcpTransportIF', 'JadePatchControlInterface', 'JadePrintData', 
                             'JadePrintDirect', 'JadePrintPage', 'JadeProfiler', 'JadeRelationalAttributeIF', 
                             'JadeRelationalEntityIF', 'JadeRelationalQueryProviderIF', 'JadeReport', 
                             'JadeReportWriterManager', 'JadeReportWriterReport', 'JadeReportWriterSecurity', 
                             'JadeRpsDataPumpIF', 'JadeSerialPort', 'JadeSSLContext', 'JadeSkin', 
                             'JadeSkinApplication', 'JadeSkinArea', 'JadeSkinCategory', 'JadeSkinControl', 
                             'JadeSkinEntity', 'JadeSkinForm', 'JadeSkinMenu', 'JadeSkinRoot', 
                             'JadeSkinSimpleButton', 'JadeSkinWindow', 'JadeSkinWindowStateImage', 
                             'JadeSOAPException', 'JadeTableCell', 'JadeTableColumn', 'JadeTableElement', 
                             'JadeTableRow', 'JadeTableSheet', 'JadeTcpIpProxy', 'JadeTestCase', 
                             'JadeTestListenerIF', 'JadeTestRunner', 'JadeTransactionTrace', 'JadeWebService', 
                             'JadeWebServiceConsumer', 'JadeWebServiceProvider', 'JadeWebServiceSoapHeader', 
                             'JadeWebServiceUnknownHeader', 'JadeX509Certificate', 'JadeXMLAttribute', 
                             'JadeXMLCDATA', 'JadeXMLCharacterData', 'JadeXMLComment', 'JadeXMLDocument', 
                             'JadeXMLDocumentParser', 'JadeXMLDocumentType', 'JadeXMLElement', 
                             'JadeXMLException', 'JadeXMLNode', 'JadeXMLParser', 'JadeXMLProcessingInstruction', 
                             'JadeXMLText', 'List', 'Locale', 'LocaleFormat', 'LocaleFullInfo', 
                             'LocaleNameInfo', 'Lock', 'LockArray', 'LockContentionInfo', 'LockException', 
                             'MemberKeyDictionary', 'MenuItem', 'MergeIterator', 'MethodCallDesc', 
                             'MultiMediaType', 'NamedPipe', 'Node', 'NormalException', 'Notification', 
                             'NotificationArray', 'NotificationException', 'NumberFormat', 'Object', 
                             'ObjectArray', 'ObjectByObjectDict', 'ObjectLongNameDict', 'ObjMethodCallDesc', 
                             'ObjectSet', 'ODBCException', 'OleObject', 'PointArray', 'PrimMethodCallDesc', 
                             'Printer', 'Process', 'ProcessDict', 'ProcessStackArray', 'RealArray', 'Rectangle', 
                             'RelationalView', 'RootSchemaSession', 'Schema', 'SchemaEntity', 
                             'SchemaEntityNumberDict', 'Script', 'Set', 'SortActor', 'SortActorArray', 'Sound', 
                             'StringArray', 'StringUtf8Array', 'System', 'SystemException', 'TcpIpConnection', 
                             'TimeArray', 'TimeFormat', 'TimeStampArray', 'TimeStampIntervalArray', 
                             'TranslatableString', 'Type', 'UserInterfaceException', 'WebSession']
        #get user Classes
        vars_classes_words = self.getVars(self.raw)
        jade_sysCls_words.extend(vars_classes_words)
        self.addJadeSysCls(jade_sysCls_words)
        
        
    def addJadeResWord(self, words):
        self.addWords(words, self.jade_ResWord_format)
        
    def addJadeSysVar(self, words):
        self.addWords(words, self.jade_sysVar_format)
        
    def addJadeSysCls(self, words):
        self.addWords(words, self.jade_sysCls_format)

    def getBlock(self, rawText, startWord, endWord):
        start_re = "(" + startWord + ")"
        
        if type(endWord) == tuple:
            end_re = "(" + str(endWord[0]) + ")|(" + str(endWord[1]) + ")"
        elif type(endWord) == str:
            end_re = "(" + endWord + ")"
        
        pattern = start_re + ".+?" + end_re
        block = re.search(pattern, rawText, re.DOTALL).group()
        block.strip(startWord)
        block.strip(endWord[0])
        block.strip(endWord[1])
        
        return block
    
    def getVars(self, rawText): 
        #get the vars block and get ride of lines feeds
        block = self.getBlock(rawText, "vars", "begin").replace("\n","")
        pattern = ":\s*?([A-Z][a-zA-Z_0-9]{0,29})\s*?;"
        userClasses = re.findall(pattern, block)
        return userClasses
        